package com.group2.operations.shiro;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.CachingSessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

public class RedisSessionDAO extends CachingSessionDAO{
    public static final String SESSION_PREFIX = "shiro_prefix";
    public static final int DEFAULT_TIME_OUT = 30;

    @Autowired
    private RedisTemplate redisTemplate;

//    public void setRedisTemplate(RedisTemplate redisTemplate) {
//        this.redisTemplate = redisTemplate;
//    }

    @Override
    protected void doUpdate(Session session) {
        saveSession(session);
    }

    @Override
    protected void doDelete(Session session) {
        if(session != null) {
            redisTemplate.delete(SESSION_PREFIX + session.getId());
        }
    }

    @Override
    protected Serializable doCreate(Session session) {
        Serializable sessionId = generateSessionId(session);
        assignSessionId(session, sessionId);
        saveSession(session);
        return sessionId;
    }

    @Override
    protected Session doReadSession(Serializable sessionId) {
        if(sessionId != null) {
            Session session = (Session) redisTemplate.opsForValue().get(SESSION_PREFIX + sessionId);
            return session;
        }
        return null;
    }

    public void saveSession(Session session) {
        if(session != null && session.getId() != null) {
            redisTemplate.opsForValue().set(SESSION_PREFIX+session.getId(), session, DEFAULT_TIME_OUT, TimeUnit.MINUTES);
        }
    }

    @Override
    public Collection<Session> getActiveSessions() {
        Set<Session> sessions = new HashSet<>();
        Set<byte[]> keys = redisTemplate.keys(SESSION_PREFIX + "*");
        if(keys != null && keys.size() > 0) {
            for(byte[] key : keys) {
                Session s = (Session) redisTemplate.opsForValue().get(key);
                sessions.add(s);
            }
        }
        return sessions;
    }
}
